package com.kfyang.manualgear.daoplugin.reference;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.ProcessingContext;
import com.kfyang.manualgear.daoplugin.Constants;
import com.kfyang.manualgear.daoplugin.util.PsiUtils;
import org.jetbrains.annotations.NotNull;

public class ConstructReferenceContributor extends PsiReferenceContributor {

    @Override
    public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
        registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiLiteralExpression.class), new PsiReferenceProvider() {
            @Override
            public PsiReference @NotNull [] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext processingContext) {
//                ArrayList<PsiReference> referenceList = new ArrayList<>();
                PsiElement annotation0 = PsiUtils.findParent(element, 3);
                if (!(annotation0 instanceof PsiAnnotation annotation) ||
                    (!Constants.CONSTRUCT_ANNO.equals(annotation.getQualifiedName()))
                ) {
                    return new PsiReference[0];
                }
                PsiElement method0 = PsiUtils.findParent(annotation, 2);
                if (!(method0 instanceof PsiMethod method)) {
                    return new PsiReference[0];
                }
                Project project = element.getProject();
                PsiTypeElement returnTypeElement = method.getReturnTypeElement();


                if (returnTypeElement == null) {
                    return new PsiReference[0];
                }
                String className;
                if (returnTypeElement.getText().startsWith("List<") || returnTypeElement.getText().startsWith("PageResult<")) {
                    String canonicalText = returnTypeElement.getType().getCanonicalText();
                    className = canonicalText.substring(canonicalText.indexOf('<') + 1, canonicalText.length() - 1);
                } else {
                    className = returnTypeElement.getType().getCanonicalText();
                }

                // 找entity中的构造器
                PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(className, GlobalSearchScope.allScope(project));
                if (psiClass == null) {
                    return new PsiReference[0];
                }
                PsiLiteralExpression toReference = null;
                for (PsiMethod constructor : psiClass.getConstructors()) {
                    if (constructor.hasAnnotation(Constants.CONSTRUCT_ANNO)) {
                        PsiAnnotation constructorAnno = constructor.getAnnotation(Constants.CONSTRUCT_ANNO);
                        PsiLiteralExpression tempReference = (PsiLiteralExpression) constructorAnno.findAttributeValue("value");
                        if (tempReference != null && tempReference.getText().equals(annotation.findAttributeValue("value").getText())) {
                            toReference = tempReference;
                            break;
                        }
                    }
                }
                if (toReference == null) return new PsiReference[0];
                return new PsiReference[]{new ConstructReference(element, new TextRange(0, element.getText().length()), toReference)};
            }
        });
    }
}
